﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using devtm.Aop.InternalProcess.Cache;
using devtm.Aop.InternalProcess;
using devtm.Aop.Event;
using devtm.Aop.InternalProcess.Lock;

namespace devtm.Aop.Behavior
{


    public class LockAttribute : InterceptMethodAttribute
    {


        private static LockDictionnary _locks = new LockDictionnary();        


        public LockAttribute()
            : base()
        {
            
        }


        public override void EntryMethod(object sender, InterceptEventArgs args)
        {


            LockItem c;
            ILockStrategy instance = null;
            uint key;

            Type StrategyType = args.Properties.TryGet("StrategyType") as Type;

            if (StrategyType == null)
                StrategyType = typeof(LockStrategy);

            instance = _locks.GetInstanceStrategyFor<ILockStrategy>(StrategyType);

            // Est ce que l'on doit locker
            if (instance.GetKey(args, out key))
            {
                // On récupère le conteneur
                _locks.Get(key, out c);

                // on passe un par un
                c.SyncLock.EnterWriteLock();

                args.Tag = c;

            }
            else
            {

            }


        }



        public override void ExitMethod(object sender, InterceptEventArgs args)
        {

            LockItem c = args.Tag as LockItem;

            if (c != null && c.SyncLock.IsWriteLockHeld)
                c.SyncLock.ExitWriteLock();

        }


        #region Properties

        public string Key { get; set; }
        public int Time { get; set; }
        public bool Sliding { get; set; }
        public Type StrategyType { get; set; }
        
        #endregion


    }
}
